package com.surfilter.msmp.web.system.controller;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.surfilter.msmp.common.model.Authorities;
import com.surfilter.msmp.common.model.Menu;
import com.surfilter.msmp.common.model.OauthToken;
import com.surfilter.msmp.common.model.User;
import com.surfilter.msmp.common.service.*;
import com.surfilter.msmp.web.common.BaseController;
import com.surfilter.msmp.web.common.JsonResult;
import com.surfilter.msmp.web.common.config.JdbcTokenStore;
import com.surfilter.msmp.web.common.enums.EsCensusEnum;
import com.surfilter.msmp.web.common.utils.StringUtil;
import com.surfilter.msmp.web.system.service.CensusService;
import com.wangfan.endecrypt.utils.EndecryptUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.client.RestHighLevelClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.wf.jwtp.provider.Token;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

@Api(value = "个人信息", tags = "main")
@RequestMapping("${api.version}/")
@Controller
public class MainController extends BaseController {

    Logger logger = LoggerFactory.getLogger(MainController.class);

    @Autowired
    private UserService userService;
    @Autowired
    private JdbcTokenStore tokenStore;
    @Autowired
    private AuthoritiesService authoritiesService;
    @Autowired
    private MenuService menuService;
    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private OauthTokenService oauthTokenService;

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private CensusService censusService;
    /*@ApiIgnore
    @RequestMapping({"/", "/index"})
    public String index() {
        return "redirect:index.html";
    }*/

    @ResponseBody
    @ApiOperation(value = "获取个人信息")
    @ApiImplicitParam(name = "access_token", value = "令牌", required = true, dataType = "String", paramType = "query")
    @GetMapping("user/info")
    public JsonResult userInfo(HttpServletRequest request) {
        User user = userService.selectById(getLoginUserId(request));
        List<Authorities> auths = new ArrayList<>();
        for (String auth : getLoginToken(request).getPermissions()) {
            Authorities t = new Authorities();
            t.setAuthority(auth);
            auths.add(t);
        }
        user.setAuthorities(auths);
        return JsonResult.ok().put("user", user);
    }

    @ResponseBody
    @ApiOperation(value = "用户登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "账号", required = true, dataType = "String", paramType = "form"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String", paramType = "form")
    })
    @PostMapping("user/login")
    public JsonResult login(String username, String password) {
        User user = userService.getByUsername(username);
        if (user == null) {
            return JsonResult.error("账号不存在");
        } else if (!user.getPassword().equals(EndecryptUtils.encrytMd5(password))) {
            return JsonResult.error("密码错误");
        } else if (user.getState() != 0) {
            return JsonResult.error("账号被锁定");
        }
        String[] roles = arrayToString(userRoleService.getRoleIds(user.getUserId()));
        String[] permissions = listToArray(authoritiesService.listByUserId(user.getUserId()));
        Token token = tokenStore.createNewToken(String.valueOf(user.getUserId()), permissions, roles);
        return JsonResult.ok("登录成功").put("access_token", token.getAccessToken());
    }

    @ResponseBody
    @ApiOperation(value = "获取所有菜单")
    @ApiImplicitParam(name = "access_token", value = "令牌", required = true, dataType = "String", paramType = "query")
    @GetMapping("user/menu")
    public JsonResult userMenu(HttpServletRequest request) {
        // 获取当前用户的权限
        Token token = getLoginToken(request);
        String[] auths = token.getPermissions();
        // 查询所有的菜单
        List<Menu> menus = menuService.selectList(new EntityWrapper<Menu>().orderBy("sort_number", true));
        // 移除没有权限的菜单
        Iterator<Menu> iterator = menus.iterator();
        while (iterator.hasNext()) {
            Menu next = iterator.next();
            boolean haveAuth = false;
            for (String auth : auths) {
                if (StringUtil.isBlank(next.getAuthority()) || next.getAuthority().equals(auth)) {
                    haveAuth = true;
                }
            }
            if (!haveAuth) {
                iterator.remove();
            }
        }
        // 去除空的目录
        iterator = menus.iterator();
        while (iterator.hasNext()) {
            Menu next = iterator.next();
            if (StringUtil.isBlank(next.getMenuUrl())) {
                boolean haveSub = false;
                for (Menu t : menus) {
                    if (t.getParentId().equals(next.getMenuId())) {
                        haveSub = true;
                        break;
                    }
                }
                if (!haveSub) {
                    iterator.remove();
                }
            }
        }
        return JsonResult.ok().put("data", getMenuTree(menus, -1));
    }

    // 递归转化树形菜单
    private List<Map<String, Object>> getMenuTree(List<Menu> menus, Integer parentId) {
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < menus.size(); i++) {
            Menu temp = menus.get(i);
            if (parentId == temp.getParentId()) {
                Map<String, Object> map = new HashMap<>();
                map.put("name", temp.getMenuName());
                map.put("icon", temp.getMenuIcon());
                map.put("url", StringUtil.isBlank(temp.getMenuUrl()) ? "javascript:;" : temp.getMenuUrl());
                map.put("subMenus", getMenuTree(menus, menus.get(i).getMenuId()));
                list.add(map);
            }
        }
        return list;
    }

    private String[] listToArray(List<String> list) {
        String[] strs = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            strs[i] = list.get(i);
        }
        return strs;
    }

    private String[] arrayToString(Object[] objs) {
        String[] strs = new String[objs.length];
        for (int i = 0; i < objs.length; i++) {
            strs[i] = String.valueOf(objs[i]);
        }
        return strs;
    }

    //判断用户登录是否超时
    @PostMapping("/pub/loginOut")
    @ResponseBody
    public boolean landTimeOut(HttpServletRequest request) {
        Integer tokenId = getLoginTokenId(request);
        if (tokenId != null) {
            EntityWrapper<OauthToken> entityWrapper = new EntityWrapper<>();
            entityWrapper.where("token_id=" + tokenId);
            OauthToken oauthToken = oauthTokenService.selectOne(entityWrapper);
            if (oauthToken.getExpireTime().getTime() < new Date().getTime()) {
                return true;
            }
        }
        return false;
    }


    /**
     * 判断图片是否存在
     *
     * @param url
     * @return
     */
    @PostMapping("/pic/isexit")
    @ResponseBody
    public boolean isExistPic(String url) {
        try {
            if (StringUtils.isNotBlank(url)) {
                URL res = new URL(url);
                // 返回一个 URLConnection 对象，它表示到 URL 所引用的远程对象的连接。
                URLConnection uc = res.openConnection();
                HttpURLConnection httpUrlConnection = (HttpURLConnection) uc;
                String code = String.valueOf(httpUrlConnection.getResponseCode());
                if (code.startsWith("2")) {
                    return true;
                }
            }
        } catch (Exception e) {
            logger.error(url + "连接异常");
        }
        return false;
    }


    /**
     * 入口地址更新按日期统计
     * @author wyh
     */
    @GetMapping("/census/source")
    @ResponseBody
    public Map<String, String> sourceCensus(String type) throws IOException {
        if (StringUtils.isBlank(type)){
            type = "day";
        }
        return censusService.census(EsCensusEnum.UPDATE_LOG,type);
    }




    /**
     * 封堵日志按日期统计
     * @author wyh
     */
    @GetMapping("/census/block")
    @ResponseBody
    public Map<String, String> blockCensus(String type) {
        if (StringUtils.isBlank(type)) {
            //默认按日期统计
            type = "day";
        }
        return censusService.census(EsCensusEnum.BLOCK_LOG,type);
    }

}
